﻿using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace 新蒙蔽机器人
{
    public class plugin
    {
        public TTS tts;
        public Gift gift = new Gift();
        public static string BASEDIR = AppDomain.CurrentDomain.BaseDirectory + @"Addons\ttsc\";
        public bool inProc = false;
        public void start()
        {
            SendMSG("bot.oninit;", true);
            SendMSG("bot.onswitch(" + false + ");", true);
            tts = new Local();
            tts.enableSpk = false;
            tts.run();
            gift.packges.Add(new Packge { name = "default" });
            gift.packges[0].setPath(BASEDIR+"默认音效包.npkg");
            Thread td = new Thread(new ThreadStart(()=> {
                inProc = true;
                gift.packges[0].unpack();
                inProc = false;
            }));
            td.Start();
        }

        public void stop()
        {
            tts.stop();
            DeleteFolder(BASEDIR);
            new Config(this).save();
            
        }

        public void dmshow(string danmuInfo)
        {
            DanmuInfo o=TransToEntity(danmuInfo);
            tts.addContent(o.logtext, o.nickname);
            SendMSG("main.playsound:"+ gift.play(o.logtext),true);
        }
        public void ActionLog(string danmuInfo)
        {
            DanmuInfo o = TransToEntity(danmuInfo);
            if ("[TTS]Start;".Equals(o.logtext))
            {
                tts.enableSpk = true;
                tts.addContent("机器人启动", "新懵逼");
            }
            if ("[TTS]Stop;".Equals(o.logtext))
            {
                tts.enableSpk = false;
                tts.stop();
            }
            if (danmuInfo.IndexOf("[TTS]SetRate") > -1)
            {
                string rate = o.logtext.Substring(13).TrimEnd(';');
                tts.setVoiceSpeed(double.Parse(rate));
            }
            if (danmuInfo.IndexOf("[TTS]SetVol") > -1)
            {
                string vol = o.logtext.Substring(12).TrimEnd(';');
                tts.setVoiceVol(double.Parse(vol));
            }
        }
        public void admin()
        {
            if (inProc)
            {
                System.Windows.Forms.MessageBox.Show("准备操作正在进行中，请稍后再试...");
                return;
            }
            ManagerForm d = new ManagerForm(this);
            d.Show();
        }
        private void DeleteOld()
        {
            if (File.Exists(AppDomain.CurrentDomain.BaseDirectory+"Addons\\语音郎读机器人.dll"))
            {
                MessageBox.Show("旧版机器人与新版机器人冲突,正为您删除旧版,请确定!","警告", MessageBoxButtons.OK);
            }
        }
        private void DeleteFolder(string dir)
        {
            try
            {
                foreach (string d in Directory.GetFileSystemEntries(dir))
                {
                    if (d.IndexOf(".npkg",StringComparison.OrdinalIgnoreCase)>-1)
                    {
                        continue;
                    }
                    if (File.Exists(d))
                    {
                        FileInfo fi = new FileInfo(d);
                        if (fi.Attributes.ToString().IndexOf("ReadOnly") != -1)
                            fi.Attributes = FileAttributes.Normal;
                        File.Delete(d);//直接删除其中的文件  
                    }
                    else
                    {
                        DirectoryInfo d1 = new DirectoryInfo(d);
                        if (d1.GetFiles().Length != 0)
                        {
                            DeleteFolder(d1.FullName);////递归删除子文件夹
                        }
                        Directory.Delete(d);
                    }
                }
            }
            catch (Exception)
            {

            }
        }

        #region 核心通讯
        public event EventHandler SMSG;
        private void SendMSG(string text,bool action=false)
        {
            string _text = "{dl_title}";
            if (action)
            {
                _text = "{action}";
            }
            SMSG(new object[] { _text + text }, null);
        }

        private DanmuInfo TransToEntity(string danmuInfo)
        {
            try
            {
                XmlSerializer xmls = new XmlSerializer(typeof(DanmuInfo));
                return (DanmuInfo)xmls.Deserialize(new StringReader(danmuInfo));
            }
            catch (Exception)
            {
                return null;
            }
            
        }
        #endregion

    }
    class Config
    {
        private plugin father;
        private string filename = AppDomain.CurrentDomain.BaseDirectory + "conf.ini";
        public Config(plugin fa)
        {
            father = fa;
        }
        public void load()
        {
            //father.gsEnableSpk=ReadIniKeys("bot", "EnableSpk", filename) =="1"?true:false;
            father.tts.disableSpkGift = ReadIniKeys("bot", "DisableSpkGift ", filename) == "1" ? true : false;
            father.tts.noName = ReadIniKeys("bot", "NoName ", filename) == "1" ? true : false;
            father.gift.enableVoice = ReadIniKeys("bot", "EnableVoice ", filename) == "1" ? true : false;
            father.gift.need_filter = ReadIniKeys("bot", "NeedFilter", filename)=="1"?true:false;
            father.tts.enableSpk= ReadIniKeys("bot", "EnableSpeak", filename) == "1" ? true : false;
        }
        public void save()
        {
           // WriteIniKeys("bot", "EnableSpk", father.gsEnableSpk ? "1" : "0", filename);
            WriteIniKeys("bot", "DisableSpkGift", father.tts.disableSpkGift? "1" : "0", filename);
            WriteIniKeys("bot", "NoName", father.tts.noName ? "1" : "0", filename);
            WriteIniKeys("bot", "EnableVoice", father.gift.enableVoice ? "1" : "0", filename);
            WriteIniKeys("bot", "NeedFilter", father.gift.need_filter ? "1" : "0", filename);
            WriteIniKeys("bot", "EnableSpeak", father.tts.enableSpk ? "1" : "0", filename);
        }
        
        #region INI操作
        [DllImport("kernel32")]
        private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);

        [DllImport("kernel32")]
        private static extern int GetPrivateProfileString(string lpAppName, string lpKeyName, string lpDefault, StringBuilder lpReturnedString, int nSize, string lpFileName);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern uint GetPrivateProfileSection(string lpAppName, IntPtr lpReturnedString, uint nSize, string lpFileName);

        private string ReadString(string section, string key, string def, string filePath)
        {
            StringBuilder temp = new StringBuilder(1024);

            try
            {
                GetPrivateProfileString(section, key, def, temp, 1024, filePath);
            }
            catch
            { }
            return temp.ToString();
        }
        /// <summary>
        /// 根据section，key取值
        /// </summary>
        /// <param name="section"></param>
        /// <param name="keys"></param>
        /// <param name="filePath">ini文件路径</param>
        /// <returns></returns>
        public virtual string ReadIniKeys(string section, string keys, string filePath)
        {
            return ReadString(section, keys, "", filePath);
        }

        /// <summary>
        /// 保存ini
        /// </summary>
        /// <param name="section"></param>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="filePath">ini文件路径</param>
        public virtual void WriteIniKeys(string section, string key, string value, string filePath)
        {
            WritePrivateProfileString(section, key, value, filePath);
        }
        #endregion
    }

    [Serializable]
    public class DanmuInfo
    {
        public string logtext { get; set; }
        [Obsolete]
        public string uid { get; set; }
        public string bilibiliuid { get; set; }
        public string nickname { get; set; }
        public string datetime { get; set; }
        public int admin { get; set; }
        public int member { get; set; }
        public int vip { get; set; }
        public string roomid { get; set; }
        public string extra_info { get; set; }
        public string type { get; set; }
    }
}
